package com.niit.scala

/**
 * Date:2025/3/19
 * Author：Ys
 * Description:
 *
 * 继承  抽象类 特质 多态  样例类
 *
 */
object Base06 {

  //1.继承：子类继承于父类，子类会自动拥有父类的属性和方法
  class Person {  // 父类
    var name: String = _
    var age: Int = _
    def eat(): Unit = {
      println(this.name+"要吃饭~~")
    }
  }

  //老师类
  class Teacher extends Person

  //学生类
  class Student extends Person

  //2.抽象类：抽象类不能实例化，只能用被继承，子类必须重写父类的抽象方法，否则子类也属于抽象类
  // 抽象的关键 abstract
  //定义一个 形状的抽象类，在该类中定义一个抽象方法，求面积
  abstract class Shape{
    def area():Double  //没有方法体的方法就是抽象方法，抽象方法一定是在抽象类或者特质(接口)当中
  }
  //定义一个圆形的类，继承于形状类，重写area方法，求圆的面积
  class Circle(var r:Double) extends Shape{
    override def area(): Double = {
      Math.PI*r*r
    }
  }
  //定义一个矩形的类，继承于形状类，重写area方法，求矩形的面积
  class Rectangle(var w:Double,var h:Double) extends Shape{
    override def area(): Double = {
      w*h
    }
  }

  /*
  3.特质： 特质就是接口，可以定义多个特质，多个特质之间用with关键字进行连接
         关键字：trait
        特质可以提高代码的复用性，减少代码的冗余，提高代码的扩展性，提高代码的维护性
        类与特质是继承的关系，类与类是单继承，类与特质是多继承
        特质中可以普通字段、抽象字段 、普通方法 、抽象方法
        如果特质只有抽象内容叫做瘦接口，如果既有抽象又有具体内容，叫做富接口
   */
  trait Logger{
    def log(msg:String)
  }

  trait File{
    def write(msg:String)
  }

  trait Redis{
    def put(msg:String)
  }

  class ConsoleLogger extends Logger with File with Redis{
    override def log(msg: String): Unit = println("日志打印："+msg)

    override def write(msg: String): Unit = println("文件写入："+msg)

    override def put(msg: String): Unit = println("redis写入："+msg)
  }

  /*
    样例类：是一种特殊的类，一般用于保存数据，在后面数据分析中的并发编程上会用很多
    格式：class 类名([var/val]参数1:类型,参数2:类型) {}
      变量修饰符不写的情况下默认是val
     定义一个样例类People 其中姓名不可改变 年龄可以改变
   */
  case class People(name:String,var age:Int = 18)

  def main(args: Array[String]): Unit = {

    val people = People("张三",20)
    println(s"name:${people.name},age:${people.age}")

    val teacher = new Teacher
    teacher.name = "张三"
    teacher.age = 30
    teacher.eat()
    val student = new Student
    student.name = "李四"
    student.age = 20
    student.eat()

    //多态： 父类引用指向子类对象，子类对象可以调用父类的方法。 父类去调用子类 子类去承接父类
    val circle:Shape = new Circle(10)
    println(circle.area())

    val rectangle:Shape = new Rectangle(10,20)
    println(rectangle.area())

    val consoleLogger = new ConsoleLogger
    consoleLogger.log("hello")
    consoleLogger.write("hello")
    consoleLogger.put("hello")


  }


}
